package com.cmz.common.utils;

import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;

/**
 * @author cmz
 * @date 2020/6/2 09:13
 */
@Slf4j
@NoArgsConstructor
public class JsonUtils {
    private final static ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {
        OBJECT_MAPPER.configure(JsonParser.Feature.ALLOW_COMMENTS, true);
        OBJECT_MAPPER.configure(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES, true);
        OBJECT_MAPPER.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    }

    /**
     * 将对象 序列化成json string
     * @param obj 对象
     * @return json string
     */
    public static String toJsonString(Object obj) {
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (JsonGenerationException | JsonMappingException e) {
            // $NON-NLS-1$
            log.error("toJSONString(Object) Json exception", e);
        } catch (IOException e) {
            // $NON-NLS-1$
            log.error("toJSONString(Object) IO exception", e);
        }
        return null;
    }

    /**
     * 将json string反序列化成对象
     *
     * @param json          json string
     * @return 对象
     */
    public static Object parse(String json) {
        try {
            return OBJECT_MAPPER.readValue(json, Object.class);
        } catch (JsonParseException | JsonMappingException e) {
            log.error("parse(String) Json exception", e);
        } catch (IOException e) {
            log.error("parse(String) IO exception", e);
        }
        return null;
    }

    /**
     * 将json string反序列化成对象
     *
     * @param json          json string
     * @param targetClass   对象类型
     * @return 对象
     */
    public static <T> T parseObject(String json, Class<T> targetClass) {
        try {
            return OBJECT_MAPPER.readValue(json, targetClass);
        } catch (JsonParseException | JsonMappingException e) {
            log.error("parseObject(String, Class<T>) Json exception", e);
        } catch (IOException e) {
            log.error("parseObject(String, Class<T>) IO exception", e);
        }
        return null;
    }

    /**
     * 将json array、map反序列化为对象
     *
     * @param json          json string
     * @param typeReference 类型转换
     * @return 对象
     */
    public static <T> T parseObject(String json, TypeReference<T> typeReference) {
        try {
            return (T) OBJECT_MAPPER.readValue(json, typeReference);
        } catch (JsonParseException | JsonMappingException e) {
            log.error("parseObject(String, TypeReference<T> Json exception", e);
        } catch (IOException e) {
            log.error("parseObject(String, TypeReference<T>) IO exception", e);
        }
        return null;
    }
}
